﻿
using System;
using LuaInterface;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Reflection;
using LuaFramework;

public delegate object LuaToParamFunc(IntPtr L);

public class TryCatchInfo
{
	public Type type;
	public string name;
	public bool isStatic;
	public object Self {
		get {
			return isStatic ? null : ToLua.ToObject (TryCatch.L, 1);
		}
	}
}

public delegate void ManualFunction(TryCatchInfo info);

public class TryCatch : TryCatchInfo
{
	static List<LuaCSFunction> funcList = new List<LuaCSFunction>();
	static void InitFuncList()
	{
		funcList.Add (func0);
		funcList.Add (func1);
		funcList.Add (func2);
		funcList.Add (func3);
		funcList.Add (func4);
		funcList.Add (func5);
		funcList.Add (func6);
		funcList.Add (func7);
		funcList.Add (func8);
		funcList.Add (func9);
		funcList.Add (func10);
		funcList.Add (func11);
		funcList.Add (func12);
		funcList.Add (func13);
		funcList.Add (func14);
		funcList.Add (func15);
		funcList.Add (func16);
		funcList.Add (func17);
		funcList.Add (func18);
		funcList.Add (func19);
		funcList.Add (func20);
		funcList.Add (func21);
		funcList.Add (func22);
		funcList.Add (func23);
		funcList.Add (func24);
		funcList.Add (func25);
		funcList.Add (func26);
		funcList.Add (func27);
		funcList.Add (func28);
		funcList.Add (func29);
		funcList.Add (func30);
		funcList.Add (func31);
		funcList.Add (func32);
		funcList.Add (func33);
		funcList.Add (func34);
		funcList.Add (func35);
		funcList.Add (func36);
		funcList.Add (func37);
		funcList.Add (func38);
		funcList.Add (func39);
		funcList.Add (func40);
		funcList.Add (func41);
		funcList.Add (func42);
		funcList.Add (func43);
		funcList.Add (func44);
		funcList.Add (func45);
		funcList.Add (func46);
		funcList.Add (func47);
		funcList.Add (func48);
		funcList.Add (func49);
		funcList.Add (func50);
		funcList.Add (func51);
		funcList.Add (func52);
		funcList.Add (func53);
		funcList.Add (func54);
		funcList.Add (func55);
		funcList.Add (func56);
		funcList.Add (func57);
		funcList.Add (func58);
		funcList.Add (func59);
		funcList.Add (func60);
		funcList.Add (func61);
		funcList.Add (func62);
		funcList.Add (func63);
		funcList.Add (func64);
		funcList.Add (func65);
		funcList.Add (func66);
		funcList.Add (func67);
		funcList.Add (func68);
		funcList.Add (func69);
		funcList.Add (func70);
		funcList.Add (func71);
		funcList.Add (func72);
		funcList.Add (func73);
		funcList.Add (func74);
		funcList.Add (func75);
		funcList.Add (func76);
		funcList.Add (func77);
		funcList.Add (func78);
		funcList.Add (func79);
		funcList.Add (func80);
		funcList.Add (func81);
		funcList.Add (func82);
		funcList.Add (func83);
		funcList.Add (func84);
		funcList.Add (func85);
		funcList.Add (func86);
		funcList.Add (func87);
		funcList.Add (func88);
		funcList.Add (func89);
		funcList.Add (func90);
		funcList.Add (func91);
		funcList.Add (func92);
		funcList.Add (func93);
		funcList.Add (func94);
		funcList.Add (func95);
		funcList.Add (func96);
		funcList.Add (func97);
		funcList.Add (func98);
		funcList.Add (func99);
	}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func0(IntPtr L){return TryCatch.list [0]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func1(IntPtr L){return TryCatch.list [1]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func2(IntPtr L){return TryCatch.list [2]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func3(IntPtr L){return TryCatch.list [3]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func4(IntPtr L){return TryCatch.list [4]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func5(IntPtr L){return TryCatch.list [5]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func6(IntPtr L){return TryCatch.list [6]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func7(IntPtr L){return TryCatch.list [7]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func8(IntPtr L){return TryCatch.list [8]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func9(IntPtr L){return TryCatch.list [9]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func10(IntPtr L){return TryCatch.list [10]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func11(IntPtr L){return TryCatch.list [11]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func12(IntPtr L){return TryCatch.list [12]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func13(IntPtr L){return TryCatch.list [13]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func14(IntPtr L){return TryCatch.list [14]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func15(IntPtr L){return TryCatch.list [15]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func16(IntPtr L){return TryCatch.list [16]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func17(IntPtr L){return TryCatch.list [17]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func18(IntPtr L){return TryCatch.list [18]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func19(IntPtr L){return TryCatch.list [19]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func20(IntPtr L){return TryCatch.list [20]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func21(IntPtr L){return TryCatch.list [21]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func22(IntPtr L){return TryCatch.list [22]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func23(IntPtr L){return TryCatch.list [23]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func24(IntPtr L){return TryCatch.list [24]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func25(IntPtr L){return TryCatch.list [25]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func26(IntPtr L){return TryCatch.list [26]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func27(IntPtr L){return TryCatch.list [27]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func28(IntPtr L){return TryCatch.list [28]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func29(IntPtr L){return TryCatch.list [29]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func30(IntPtr L){return TryCatch.list [30]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func31(IntPtr L){return TryCatch.list [31]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func32(IntPtr L){return TryCatch.list [32]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func33(IntPtr L){return TryCatch.list [33]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func34(IntPtr L){return TryCatch.list [34]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func35(IntPtr L){return TryCatch.list [35]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func36(IntPtr L){return TryCatch.list [36]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func37(IntPtr L){return TryCatch.list [37]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func38(IntPtr L){return TryCatch.list [38]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func39(IntPtr L){return TryCatch.list [39]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func40(IntPtr L){return TryCatch.list [40]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func41(IntPtr L){return TryCatch.list [41]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func42(IntPtr L){return TryCatch.list [42]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func43(IntPtr L){return TryCatch.list [43]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func44(IntPtr L){return TryCatch.list [44]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func45(IntPtr L){return TryCatch.list [45]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func46(IntPtr L){return TryCatch.list [46]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func47(IntPtr L){return TryCatch.list [47]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func48(IntPtr L){return TryCatch.list [48]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func49(IntPtr L){return TryCatch.list [49]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func50(IntPtr L){return TryCatch.list [50]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func51(IntPtr L){return TryCatch.list [51]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func52(IntPtr L){return TryCatch.list [52]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func53(IntPtr L){return TryCatch.list [53]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func54(IntPtr L){return TryCatch.list [54]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func55(IntPtr L){return TryCatch.list [55]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func56(IntPtr L){return TryCatch.list [56]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func57(IntPtr L){return TryCatch.list [57]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func58(IntPtr L){return TryCatch.list [58]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func59(IntPtr L){return TryCatch.list [59]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func60(IntPtr L){return TryCatch.list [60]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func61(IntPtr L){return TryCatch.list [61]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func62(IntPtr L){return TryCatch.list [62]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func63(IntPtr L){return TryCatch.list [63]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func64(IntPtr L){return TryCatch.list [64]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func65(IntPtr L){return TryCatch.list [65]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func66(IntPtr L){return TryCatch.list [66]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func67(IntPtr L){return TryCatch.list [67]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func68(IntPtr L){return TryCatch.list [68]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func69(IntPtr L){return TryCatch.list [69]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func70(IntPtr L){return TryCatch.list [70]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func71(IntPtr L){return TryCatch.list [71]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func72(IntPtr L){return TryCatch.list [72]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func73(IntPtr L){return TryCatch.list [73]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func74(IntPtr L){return TryCatch.list [74]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func75(IntPtr L){return TryCatch.list [75]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func76(IntPtr L){return TryCatch.list [76]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func77(IntPtr L){return TryCatch.list [77]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func78(IntPtr L){return TryCatch.list [78]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func79(IntPtr L){return TryCatch.list [79]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func80(IntPtr L){return TryCatch.list [80]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func81(IntPtr L){return TryCatch.list [81]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func82(IntPtr L){return TryCatch.list [82]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func83(IntPtr L){return TryCatch.list [83]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func84(IntPtr L){return TryCatch.list [84]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func85(IntPtr L){return TryCatch.list [85]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func86(IntPtr L){return TryCatch.list [86]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func87(IntPtr L){return TryCatch.list [87]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func88(IntPtr L){return TryCatch.list [88]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func89(IntPtr L){return TryCatch.list [89]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func90(IntPtr L){return TryCatch.list [90]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func91(IntPtr L){return TryCatch.list [91]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func92(IntPtr L){return TryCatch.list [92]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func93(IntPtr L){return TryCatch.list [93]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func94(IntPtr L){return TryCatch.list [94]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func95(IntPtr L){return TryCatch.list [95]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func96(IntPtr L){return TryCatch.list [96]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func97(IntPtr L){return TryCatch.list [97]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func98(IntPtr L){return TryCatch.list [98]._luaCsFunc (L);}
	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int func99(IntPtr L){return TryCatch.list [99]._luaCsFunc (L);}

	static List<TryCatch> list = new List<TryCatch>();
	public static IntPtr L;
	public static int ret = 0;
	public static Type classType;
	public ManualFunction manualFunc;
	public LuaCSFunction luaCsFunc;
	public LuaCSFunction _luaCsFunc;
	public TryCatch( ManualFunction func, string name, bool isStatic = false )
	{
		type = classType;
		manualFunc = func;
		this.name = name;
		this.isStatic = isStatic;
		_luaCsFunc = p => {
			try {
				L = p;
				ret = 0;
				manualFunc (this);
				return ret;
			} catch (Exception e) {
				if (LuaDLL.tolua_argerror(L, 1, e.Message) != 0)
				{
					string error = LuaDLL.lua_tostring(L, -1) + "("+this.type.ToString()+"."+this.name+")";
					LuaDLL.lua_pop(L, 1);
					Util.Log(error);
				}
				return 0;
			}
		};

		list.Add (this);

		if (funcList.Count == 0)
        {
			InitFuncList ();
		}

		if (funcList.Count > list.Count)
        {
			luaCsFunc = funcList [list.Count-1];
		}
        else
        {
			Util.LogError("TryCatch has no more LuaCSFunction, Please add more！");
		}
    }
}

public class ManualWrap
{
	static MethodInfo CheckObjectArray = null;
	static Dictionary<string, LuaToParamFunc> paramMap = new Dictionary<string, LuaToParamFunc>{
		{"int", L=>{ return (int)LuaDLL.lua_tonumber(L, -1);}},
		{"uint", L=>{ return (uint)LuaDLL.lua_tonumber(L, -1);}},
		{"double", L=>{ return (double)LuaDLL.lua_tonumber(L, -1);}},
		{"float", L=>{ return (float)LuaDLL.lua_tonumber(L, -1);}},
		{"short", L=>{ return (short)LuaDLL.lua_tonumber(L, -1);}},
		{"ushort", L=>{ return (ushort)LuaDLL.lua_tonumber(L, -1);}},
		{"long", L=>{ return (long)LuaDLL.lua_tonumber(L, -1);}},
		{"ulong", L=>{ return (ulong)LuaDLL.lua_tonumber(L, -1);}},
		{"byte", L=>{ return (byte)LuaDLL.lua_tonumber(L, -1);}},
		{"byteBuffer", L=>{ return ToLua.CheckByteBuffer (L, -1);}},
		{"charBuffer", L=>{ return ToLua.CheckCharBuffer (L, -1);}},
		{"stringArray", L=>{ return ToLua.CheckStringArray (L, -1);}},
		{"LuaByteBuffer", L=>{ return new LuaByteBuffer (ToLua.CheckByteBuffer (L, -1));}},
		{"[]", L=>{
				if( CheckObjectArray == null ){
					BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly;
					var methods = typeof(ToLua).GetMethods(flags);
					foreach(var mi in methods){
						if(mi.IsGenericMethod && mi.Name == "CheckObjectArray"){
							CheckObjectArray = mi;
							break;
						}
					}
				}
				string typeName = LuaDLL.lua_tostring (L, -2);
				typeName = typeName.Remove(typeName.Length-2);
				var method = CheckObjectArray.MakeGenericMethod(new Type[]{GetType(typeName)});
				var ret = method.Invoke(null, new object[]{L, -1});
				return ret;
			}
		},
	};
	static List<Assembly> list = new List<Assembly>();
	static Dictionary<string, Type> map = new Dictionary<string, Type>();
	static LuaState lua;
	public static void Out(object obj)
	{
		ToLua.Push (TryCatch.L, obj);
		TryCatch.ret =  1;
	}
	public static T Self<T>()
	{
		var obj = Vobject ();
		T self;
		try{
			self = (T)obj;
		}catch(Exception) {
			self = ((Component)obj).GetComponent<T>();
		}
		return self;
	}
	public static object Vobject(int pos = 1)
	{
		return ToLua.ToObject (TryCatch.L, pos);
	}
	public static string Vstring(int pos)
	{
		return ToLua.CheckString (TryCatch.L, pos);
	}
	public static bool Vbool(int pos)
	{
		return LuaDLL.luaL_checkboolean (TryCatch.L, pos);
	}
	public static int Vint(int pos)
	{
		return LuaDLL.luaL_checkinteger (TryCatch.L, pos);
	}
	public static float Vfloat(int pos)
	{
		return (float)LuaDLL.luaL_checknumber (TryCatch.L, pos);
	}
	public static LuaFunction Vfunction(int pos)
	{
		return ToLua.CheckLuaFunction(TryCatch.L, pos);
	}
	public static int ArgsCount()
	{
		return LuaDLL.lua_gettop (TryCatch.L);
	}
	public static void BeginClass(Type t, Type baseType, string name = null)
	{
		lua.BeginClass(t, baseType, name);
		TryCatch.classType = t;
	}
	public static void RegFunction(string name, ManualFunction func, bool isStatic = false )
	{
		lua.RegFunction (name, (new TryCatch (func, name, isStatic)).luaCsFunc);
	}
	public static void RegVar(string name, ManualFunction getFunc, ManualFunction setFunc, bool isStatic = false )
	{
		lua.RegVar (name, getFunc == null ? null : (new TryCatch (getFunc, name, isStatic)).luaCsFunc, setFunc == null ? null : (new TryCatch (setFunc, name, isStatic)).luaCsFunc);
	}
	public static void Register(LuaState luaState)
	{
		lua = luaState;
		lua.BeginModule(null);
		{
            //注释掉动态注册类接口。因为安卓和iOS都是用il2cpp打包
            /*
			BeginClass(typeof(FireElementSpace_ManualWrap), null, "Cs");
			RegFunction("__index", T=>{
				string name = Vstring(2);
				RegisterClass(name);
				LuaDLL.lua_getglobal(TryCatch.L, "Cs_"+name);
				LuaDLL.lua_pushvalue(TryCatch.L, 2);
				LuaDLL.lua_pushvalue(TryCatch.L, 3);
				LuaDLL.lua_rawset(TryCatch.L, 1);
				TryCatch.ret = 1;
			});
			lua.EndClass ();
            */

			lua.BeginModule ("UnityEngine");
			{
				BeginClass (typeof(Transform), typeof(Component));
				RegFunction("SetActive", T=>{Transform_Child.gameObject.SetActive (Vbool(-1));});
                RegFunction ("AddComponent", T => {
					var type = (Type)ToLua.CheckObject (TryCatch.L, -1, typeof(Type));
					var ret = Transform_Child.gameObject.GetComponent(type);
					if(ret == null){
						ret = Transform_Child.gameObject.AddComponent (type);
					}
					Out (ret);
				});
				RegFunction("FindChild", T => { Out(Transform_Child.Find(Vstring(-1))); });
				RegFunction("SubGet", T=>{Out( Transform_Child.GetComponent (Vstring(-1)) );});
				RegFunction("Hide", T=>{Transform_Child_Param().gameObject.SetActive (false);});
				RegFunction("Show", T=>{Transform_Child_Param().gameObject.SetActive (true);});
				RegFunction("SetText", T=>{Transform_Text(Vstring(-1));});
				// RegFunction("SetImage", T=>{
				// 	Texture2D texture = (Texture2D)Vobject(-1);
				// 	if(texture == null)
				// 	{
				// 		string picName = ToLua.ToString (TryCatch.L, -1);
				// 		if(picName != null && picName != "")
				// 		{
				//             texture = ResourceManager.LoadAsset("image", picName) as Texture2D;
				// 		}
				// 	}
				// 	Transform_Child.GetComponent<Image>().sprite = Sprite.Create(texture, new Rect(0,0,texture.width,texture.height), new Vector2(0.5f,0.5f));
				// });
                RegVar ("text", T=>{Out( Transform_Text() );}, T=>{Transform_Text(Vstring(-1));});
				RegVar ("interactable", T=>{Out( Self<Transform>().GetComponent<Selectable>().interactable );}, T=>{Self<Transform>().GetComponent<Selectable>().interactable = Vbool(-1);});
                RegVar ("enabled", T => { Out(Self<Transform>().GetComponent<Behaviour>().enabled); }, T => { Self<Transform>().GetComponent<Behaviour>().enabled = Vbool(-1); });
                RegVar ("x", T=>{Out( Self<Transform>().localPosition.x );}, T=>{var self = Self<Transform>(); var pos = self.localPosition; pos.x = Vfloat(-1); self.localPosition = pos;});
				RegVar ("y", T=>{Out( Self<Transform>().localPosition.y );}, T=>{var self = Self<Transform>(); var pos = self.localPosition; pos.y = Vfloat(-1); self.localPosition = pos;});
				RegVar ("z", T=>{Out( Self<Transform>().localPosition.z );}, T=>{var self = Self<Transform>(); var pos = self.localPosition; pos.z = Vfloat(-1); self.localPosition = pos;});
				RegVar ("width", T => {
					Out (Self<Transform> ().GetComponent<RectTransform>().sizeDelta.x);
				}, T => {
					var rt = Self<Transform> ().GetComponent<RectTransform>();
					rt.sizeDelta = new Vector2(Vfloat (-1), rt.sizeDelta.y);
				});
				RegVar ("height", T => {
					Out (Self<Transform> ().GetComponent<RectTransform>().sizeDelta.y);
				}, T => {
					var rt = Self<Transform> ().GetComponent<RectTransform>();
					rt.sizeDelta = new Vector2(rt.sizeDelta.x, Vfloat (-1));
				});
				RegVar ("size", T => {
					Out (Self<Transform> ().GetComponent<RectTransform>().sizeDelta);
				}, T => {
					var rt = Self<Transform> ().GetComponent<RectTransform>();
					rt.sizeDelta = ToLua.ToVector2(TryCatch.L, 2);
				});
				RegVar ("rect", T => {
					Out (Self<Transform> ().GetComponent<RectTransform>().rect);
				}, null);
				lua.EndClass ();

                BeginClass(typeof(Button), typeof(Component));
                RegFunction("SetBtnEnable", T=>{Self<Button>().interactable = (Vbool(-1));});
                lua.EndClass();

                BeginClass (typeof(Component), typeof(UnityEngine.Object));
				RegFunction("SetActive", T=>{Self<Component>().gameObject.SetActive (Vbool(-1));});
                RegFunction("Hide", T=>{Self<Component>().gameObject.SetActive (false);});
				RegFunction("Show", T=>{Self<Component>().gameObject.SetActive (true);});
				RegVar ("activeSelf", T=>{Out(Self<Component>().gameObject.activeSelf);}, null);
				RegVar ("onClick", null, T=>{Transform_PointerEventListener.onClick = Vfunction(-1);});
				RegVar ("onDown", null, T=>{Transform_PointerEventListener.onDown = Vfunction(-1);});
				RegVar ("onUp", null, T=>{Transform_PointerEventListener.onUp = Vfunction(-1);});
				RegVar ("onExit", null, T=>{Transform_PointerEventListener.onExit = Vfunction(-1);});
				RegVar ("onBeginDrag", null, T=>{Transform_PointerEventListener.onBeginDrag = Vfunction(-1);});
				RegVar ("onDrag", null, T=>{Transform_PointerEventListener.onDrag = Vfunction(-1);});
				RegVar ("onEndDrag", null, T=>{Transform_PointerEventListener.onEndDrag = Vfunction(-1);});
				RegVar ("onMove", null, T=>{
					LuaTypes type = LuaDLL.lua_type(TryCatch.L, -1);
					if(type == LuaTypes.LUA_TBOOLEAN){
						if(Vbool(-1)){
							Transform_PointerEventListener.onMove = null;
						}else{
							GameObject.Destroy(Self<Transform>().GetComponent<OnMoveFunc>());
						}
					}else{
						Transform_PointerEventListener.onMove = Vfunction(-1);
					}
				});
				// RegVar ("callback", null, T=>{Self<Component>().GetComponent<LuaCallback>().func = Vfunction(2);});
				RegVar ("material", T=>{Out( Self<Graphic>().material );}, T=>{Self<Graphic>().material = ((Material)Vobject(2));});
				RegVar ("color", T=>{Out( Self<Graphic>().color );}, T=>{Self<Graphic>().color = ToLua.ToColor(TryCatch.L, 2);});
				lua.EndClass ();
			}
			lua.EndModule ();
		}
		lua.EndModule ();
	}
	public static Type GetType(string typeName)
	{
		Type type;
		if( !map.TryGetValue (typeName, out type) ){
			type = Type.GetType( typeName );
			if (type == null) {
				if (list.Count == 0) {
					var currentAssembly = Assembly.GetExecutingAssembly();
					var referencedAssemblies = currentAssembly.GetReferencedAssemblies();
					foreach (var assemblyName in referencedAssemblies) {
						list.Add( Assembly.Load (assemblyName) );
					}
				}
				foreach (var assembly in list) {
					type = assembly.GetType( typeName );
					if (type != null)
						break;
				}
			}
			map.Add (typeName, type);
		}
		return type;
	}
	public static void RegisterClass( string name )
	{
        //应该没有什么类名中包含123456789这个字符串，如果有，请修改下面123456789
	    string tmp = name.Replace("FireElementSpace_", "123456789");
	    tmp = tmp.Replace('_', '.');
		string typeName = tmp.Replace ("123456789", "FireElementSpace_");
		Type type = GetType(typeName);
		if (type != null) {
			Util.Log("register class " + name);
			lua.BeginModule (null);
			{
				BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly;
				BeginClass (type, type.BaseType, "Cs_" + name);
				RegFunction ("__call", ManualFunction_Call);
				RegFunction ("New", ManualFunction_Call);
				var mis = type.GetMethods (flags);
				string currentName = "";
				foreach (var mi in mis) {
					if (!mi.IsSpecialName && currentName != mi.Name) {
						RegFunction (mi.Name, ManualFunction_RegFunc, mi.IsStatic);
						currentName = mi.Name;
					}
				}
				var fs = type.GetFields (flags);
				foreach (var mb in fs) {
					RegVar (mb.Name, ManualFunction_RegVarGetField, ManualFunction_RegVarSetField, mb.IsStatic);
				}
				var ps = type.GetProperties (flags);
				foreach (var mb in ps) {
					var getMethod = mb.GetGetMethod ();
					var setMethod = mb.GetSetMethod ();
					bool isStatic = getMethod != null ? getMethod.IsStatic : setMethod.IsStatic;
					RegVar (mb.Name, getMethod == null ? (ManualFunction)null : ManualFunction_RegVarGetProperty, setMethod == null ? (ManualFunction)null : ManualFunction_RegVarSetProperty, isStatic);
				}
				RegFunction ("__tostring", T => {
					Out (T.type.ToString ());
				});
				lua.EndClass ();
			}
			lua.EndModule ();
		}
	}
	public static object[] LuaToParams(int pos)
	{
		int count = ArgsCount () - pos + 1;
		if (count > 0) {
			List<object> list = new List<object>(count);
			object obj = null;
			while (count > 0)
			{
				LuaToParamFunc func = null;
				LuaTypes type = LuaDLL.lua_type(TryCatch.L, pos);
				if (type == LuaTypes.LUA_TTABLE) {
					LuaDLL.lua_rawgeti (TryCatch.L, pos, 1);
					if (LuaDLL.lua_isstring (TryCatch.L, -1) > 0) {
						string typeName = LuaDLL.lua_tostring (TryCatch.L, -1);
						if (typeName.EndsWith ("[]")) {
							typeName = "[]";
						}
						func = paramMap [typeName];
						if (func != null) {
							LuaDLL.lua_rawgeti (TryCatch.L, pos, 2);
							obj = func (TryCatch.L);
							LuaDLL.lua_pop (TryCatch.L, 1);
						}
					}
					LuaDLL.lua_pop (TryCatch.L, 1);
				}
				if(func == null) {
					obj = ToLua.ToVarObject (TryCatch.L, pos);
				}
				list.Add(obj);
				--count;
				++pos;
			}
			return list.ToArray();
		}
		return null;
	}
	public static void ManualFunction_Call(TryCatchInfo T)
	{
		Out (T.type.InvokeMember (null, BindingFlags.CreateInstance, null, null, LuaToParams(2)) );
	}
	public static void ManualFunction_RegFunc(TryCatchInfo T)
	{
		Out(T.type.InvokeMember (T.name, BindingFlags.InvokeMethod, null, T.Self, LuaToParams (T.isStatic ? 1 : 2)));
	}
	public static void ManualFunction_RegVarGetField(TryCatchInfo T)
	{
		Out(T.type.InvokeMember (T.name, BindingFlags.GetField, null, T.Self, null));
	}
	public static void ManualFunction_RegVarSetField(TryCatchInfo T)
	{
		T.type.InvokeMember (T.name, BindingFlags.SetField, null,T.Self, LuaToParams (ArgsCount ()));
	}
	public static void ManualFunction_RegVarGetProperty(TryCatchInfo T)
	{
		Out(T.type.InvokeMember (T.name, BindingFlags.GetProperty, null, T.Self, null));
	}
	public static void ManualFunction_RegVarSetProperty(TryCatchInfo T)
	{
		T.type.InvokeMember (T.name, BindingFlags.SetProperty, null, T.Self, LuaToParams (ArgsCount ()));
	}
	public static Transform Transform_Child_Param(int paramCount = 0)
	{
		Transform obj = Self<Transform>();
		if (ArgsCount () > 1 + paramCount) {
			string childName = ToLua.ToString (TryCatch.L, 2);
			if (childName != null && childName != "") {
				obj = obj.Find (childName);
			}
		}
		return obj;
	}
	public static Transform Transform_Child
	{
		get{
			return Transform_Child_Param(1);
		}
	}
	public static PointerEventListener Transform_PointerEventListener
	{
		get{
			Transform obj = Self<Component>().transform;
			PointerEventListener ret = obj.GetComponent<PointerEventListener>();
			return ret != null ? ret : obj.gameObject.AddComponent<PointerEventListener>();
		}
	}
	public static string Transform_Text(string text = null)
	{
		Transform obj = Transform_Child;
		if (obj != null) {
			Text txt = obj.GetComponent<Text> ();
			if (txt == null) {
				InputField input = obj.GetComponent<InputField> ();
				if (input != null) {
					if (text != null)
						input.text = text;
					else
						return input.text;
				}
			} else if (text != null) {
				txt.text = text;
			} else {
				return txt.text;
			}
		}
		return "";
	}
}

